//
//  CCQTools.swift
//  Fangxukanghan
//
//  Created by 常超群的MacBookPro on 2021/3/21.
//  
//

import UIKit
import Kingfisher
import MBProgressHUD
import MJRefresh
public class CCQTools: NSObject {
    /// 显示等待提示
    ///
    /// - Parameter view: 在传入的view上显示
    public class func showWaitingHudInView(view: UIView) {
        let hud = MBProgressHUD.showAdded(to: view, animated: true)
        hud.bezelView.style = .solidColor
        hud.bezelView.backgroundColor = .black
        hud.contentColor = .white
    }
    /// 移除等待提示
    ///
    /// - Parameter view: 在传入的view上移除
    public class func hideWaitingHudInView(view: UIView) {
        MBProgressHUD.hide(for: view, animated: true)
    }

    /// 显示文字提示
    ///
    /// - Parameters:
    ///   - text: 传入的文字
    ///   - view: 在传入的view上显示
    public class func showTextHudWithText(text:String, view: UIView) {
        let hud = MBProgressHUD.showAdded(to: view, animated: true)
        hud.mode = .text
        hud.label.text = text
        hud.label.numberOfLines = 0
        hud.hide(animated: true, afterDelay: TimeInterval(1))
    }
    
    /// tableView添加下拉刷新控件
    ///
    /// - Parameters:
    ///   - tableView: 传入的tableView
    ///   - dropDownToRefresh: 闭包回调
    @discardableResult
    public class func addDropDownToRefreshAtTableView(scrollView: UIScrollView, dropDownToRefresh: @escaping ()->()) -> MJRefreshNormalHeader {
        let mj_header = MJRefreshNormalHeader(refreshingBlock: {
            dropDownToRefresh()
        })
        scrollView.mj_header = mj_header
        return mj_header
    }
    
    /// 进入刷新状态
    ///
    /// - Parameter tableView: 传入的tableView
    public class func beginDropDownRefreshingAtTableView(scrollView: UIScrollView) {
        scrollView.mj_header?.beginRefreshing()
    }
    /// 结束刷新状态
    ///
    /// - Parameter tableView: 传入的tableView
    public class func endDropDownRefreshingAtTableView(scrollView: UIScrollView) {
        scrollView.mj_header?.endRefreshing()
    }
    /// tableView添加上拉加载刷新控件
    ///
    /// - Parameters:
    ///   - tableView: 传入的tableView
    ///   - pullToRefresh: 闭包回调
    @discardableResult
    public class func addPullToRefreshAtTableView(scrollView: UIScrollView, pullToRefresh: @escaping ()->()) -> MJRefreshAutoNormalFooter {
        let mj_footer = MJRefreshAutoNormalFooter(refreshingBlock: {
            pullToRefresh()
        })
        scrollView.mj_footer = mj_footer
        return mj_footer
    }
    /// 结束上拉加载状态
    ///
    /// - Parameter tableView: 传入的tableView
    public class func endPullToRefreshAtTableView(scrollView: UIScrollView) {
        scrollView.mj_footer?.endRefreshing()
        
    }
    /// 没数据显示没有下一页
    ///
    /// - Parameter tableView: 传入的tableView
    public class func endRefreshingWithNoMoreDataAtTableView(scrollView: UIScrollView) {
        scrollView.mj_footer?.endRefreshingWithNoMoreData()
    }
    /// 重置没有数据
    ///
    /// - Parameter tableView: 传入的tableView
    public class func resetNoMoreDataAtTableView(scrollView: UIScrollView) {
        scrollView.mj_footer?.resetNoMoreData()
    }
    ///判断字符串是否为空或者全部为空格
    public class func isBlankString(string: String?) -> Bool {
        if string == nil {
            return true
        }
        if string == "" {
            return true
        }
        if string == "NULL" {
            return true
        }
        if string?.trimmingCharacters(in: .whitespacesAndNewlines).count == 0  {
            return true
        }
        return false
    }
    /// 根据高度度求宽度
    /// - Parameters:
    ///   - text: 计算的内容
    ///   - height: 计算的高度
    ///   - font: 字体大小
    /// - Returns: 返回宽度
    public class func getWidthWithText(text: String, height: CGFloat = 30, font: CGFloat = 14) -> CGFloat {
        var string = text
        if string.isEmpty {
            string = ""
        }
        let rect = string.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: height), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: font)], context: nil);
        
        return rect.size.width
    }
    
    
    /// 根据原图片的尺寸计算图片本来高度
    public class func imageShowSize(size: CGSize) -> CGSize {
        
        /// 图片显示的最大宽度
        let MAX_IMAGE_W: CGFloat = 140.0
        /// 图片显示的最大高度
        let MAX_IMAGE_H: CGFloat = 220.0
        
        let imageWith = size.width
        let imageHeight = size.height
        //宽度大于高度
        if imageWith >= imageHeight {
            // 宽度超过标准宽度
            if imageWith > MAX_IMAGE_W {
                return CGSize(width: MAX_IMAGE_W, height: imageHeight * MAX_IMAGE_W / imageWith);
            } else {
                return size;
            }
        } else {
            if imageHeight > MAX_IMAGE_H {
                return CGSize(width: imageWith*MAX_IMAGE_W/imageHeight, height: MAX_IMAGE_W);
            } else {
                return size;
            }
        }
    }
    
    /// 设置HTML里面图片最大的宽度
    public class func htmlImageWidthAutoStr(htmlStr: String, maxWidth: CGFloat) -> String {
       let detailTextString = "<html><head><style>img{max-width:\(maxWidth);height:auto !important;width:auto !important;};</style></head><body style='margin:0; padding:0;'>\(htmlStr)</body></html>"
        return detailTextString
    }
    /// 设置富文本适应屏幕宽度
    public class func htmlImageWidthAutoStr(htmlStr: String) -> String {
       let detailTextString = "<html><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'><style>img{width:100%}</style></header><body style='margin:0; padding:0;'>\(htmlStr)</body></html>"
        return detailTextString
    }
    
    ///计算开始时间和结束时间的秒数差
    public class func differenceInsert(starTime: String, endTime: String,  fromFormatString: String) -> TimeInterval? {
        let formatter = DateFormatter()
        formatter.dateFormat = fromFormatString
        guard let startDate = formatter.date(from: starTime),
              let endDate = formatter.date(from: endTime) else {
            return nil
        }
        let time = endDate.timeIntervalSince(startDate)
        return time
    }
    /// 时间秒数转换时分秒
    public class func secondsToHoursMinutesSeconds (seconds : Int) -> (h: Int, m: Int, s: Int) {
      return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
    }
    /// 获取当前时间戳(13位)
    public class func getCurrentTimeStamp() -> String {
        let timeInterval: TimeInterval = Date().timeIntervalSince1970
        let millisecond = CLongLong(round(timeInterval * 1000))
        return "\(millisecond)"
    }
    
    /**
     压缩图片到指定大小(byte)

     @param image 原始图片
     @param maxLength 最大长度
     @return 压缩后图片
     */
    
    public class func compressImageQuality(image: UIImage, maxLength: Int) -> Data? {
        var compression: CGFloat = 1
        guard var data = image.jpegData(compressionQuality: compression) else {
            return nil
        }
        if (data.count < maxLength) {
            return data
        }
        
        var max: CGFloat = 1
        var min: CGFloat = 0
        //个人感觉6次已经足够了
        for _ in 0..<6 {
            compression = (max + min) / 2;
            data = image.jpegData(compressionQuality: compression)!;
            //这里是为了防止压缩后过小我们让图片在0.9-1.0之间
            if CGFloat(data.count) < CGFloat(maxLength) * 0.9 {
                min = compression;
            } else if (data.count > maxLength) {
                max = compression;
            } else {
                break;
            }
        }
        return data;
    }
    
    // MARK: - 在主线程中（延迟）执行
    public class func execute(_ delay: TimeInterval = 0, closure: @escaping CCQVoidClosure) {
        if delay == 0 {
            DispatchQueue.main.async {
                closure()
            }
        } else {
            DispatchQueue.main.asyncAfter(deadline: .now() + delay) { closure() }
        }
    }
    // MARK: 显示Toast

    public static func showToast(_ msg: String?) {
        execute() {
            let hud = MBProgressHUD.showAdded(to: CCQWindow, animated: true)
            hud.isUserInteractionEnabled = false
            hud.mode = .text;
            hud.label.text = msg
            hud.label.numberOfLines = 0
            hud.label.textColor = .white
            hud.bezelView.style = .solidColor
            hud.bezelView.backgroundColor = .black
            hud.hide(animated: true, afterDelay: 3.0)
        }
    }
    
    ///传入base64的字符串，可以是没有经过修改的转换成的以data开头的，也可以是base64的内容字符串，然后转换成UIImage
    public class func base64StringToUIImage(base64String: String)->UIImage? {
        var str = base64String
        // 1、判断用户传过来的base64的字符串是否是以data开口的，如果是以data开头的，那么就获取字符串中的base代码，然后在转换，如果不是以data开头的，那么就直接转换
        if str.hasPrefix("data:image") {
            guard let newBase64String = str.components(separatedBy: ",").last else {
                return nil
            }
            str = newBase64String
        }
        // 2、将处理好的base64String代码转换成NSData
        guard let imgNSData = Data(base64Encoded: str, options: NSData.Base64DecodingOptions()) else {
            return nil
        }
        // 3、将NSData的图片，转换成UIImage
        guard let codeImage = UIImage(data: imgNSData) else {
            return nil
        }
        return codeImage
    }
    
    /// 根据url下载图片
    public class func downloadImage(with urlString: String, callback: ((UIImage) -> Void)?) {
        guard let url = URL.init(string: urlString) else {
            return
        }
        let resource = ImageResource(downloadURL: url)
        KingfisherManager.shared.retrieveImage(with: resource, options: [.scaleFactor(3)], progressBlock: nil) { result in
            switch result {
                case .success(let value):
                    callback?(value.image.withRenderingMode(.alwaysOriginal))
                case .failure(let error):
                    print("下载图片出错: \(error)")
            }
        }
    }
    // 获取ip地址
    public class func getIpAddress() -> String? {
            var address : String?
            // Get list of all interfaces on the local machine:
            var ifaddr : UnsafeMutablePointer<ifaddrs>?
            guard getifaddrs(&ifaddr) == 0 else { return nil }
            guard let firstAddr = ifaddr else { return nil }
            // For each interface ...
            for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
                let interface = ifptr.pointee
                // Check for IPv4 or IPv6 interface:
                let addrFamily = interface.ifa_addr.pointee.sa_family
                if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
                    
                    // Check interface name:
                    let name = String(cString: interface.ifa_name)
                    if  name == "en0" {
                        // Convert interface address to a human readable string:
                        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                        getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len),
                                    &hostname, socklen_t(hostname.count),
                                    nil, socklen_t(0), NI_NUMERICHOST)
                        address = String(cString: hostname)
                    } else if (name == "pdp_ip0" || name == "pdp_ip1" || name == "pdp_ip2" || name == "pdp_ip3") {
                        // Convert interface address to a human readable string:
                        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                        getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len),
                                    &hostname, socklen_t(hostname.count),
                                    nil, socklen_t(1), NI_NUMERICHOST)
                        address = String(cString: hostname)
                    }
                }
            }
            freeifaddrs(ifaddr)
            
            return address
        }
}
